home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 June: Reference Library / Dev.CD Jun 95 / Dev.CD Jun 95.toast / What's New? / New System Software Extensions / QuickDraw 3D ß / Programming / SampleCode / 3DMF2PICT / 3DMF2PICTShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-05  |  12.3 KB  |  495 lines  |  [TEXT/MPCC]

  1. // Quickdraw 3D sample code
  2. //
  3. // ©1994-5 Apple Computer Inc., All Rights Reserved
  4.  
  5. // system headers
  6. #include <Desk.h>
  7. #include <Dialogs.h>
  8. #include <DiskInit.h>
  9. #include <Fonts.h>
  10. #include <Menus.h>
  11. #include <PictUtil.h>
  12. #include <QDOffScreen.h>
  13. #include <QuickDraw.h>
  14. #include <SegLoad.h>
  15. #include <StandardFile.h>
  16. #include <TextEdit.h>
  17. #include <ToolUtils.h>
  18.  
  19. // for QuickDraw 3D
  20. #include "QD3D.h"
  21. #include "QD3DMath.h"
  22. #include "QD3DDrawContext.h"
  23. #include "QD3DShader.h"
  24. #include "QD3DTransform.h"
  25. #include "QD3DGroup.h"
  26. #include "QD3DCamera.h"
  27.  
  28.  
  29. #include "3DMF2PICTShell.h"
  30. #include "3DMF2PICTSupport.h"
  31.  
  32. // get the interface to my error handler routines
  33. #include "MyErrorHandler.h"
  34.  
  35.  
  36. //-------------------------------------------------------------------------------------------
  37. // function prototypes
  38.  
  39. static void         InitToolbox( void ) ;
  40. static void         MainEventLoop( void ) ;
  41. static void         HandleKeyPress(EventRecord *event) ;
  42. static void         HandleOSEvent(EventRecord *event) ;
  43. void InitDocumentData( DocumentPtr theDocument ) ;
  44. TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
  45. void DisposeDocumentData( DocumentPtr theDocument) ;
  46. void DocumentDrawOnscreen(DocumentPtr theDocument, Rect *clipRect) ;
  47.  
  48. OSErr WritePict( PicHandle myPic, short  dstPictFRef ) ;
  49. OSErr GetOutputFileRef(short    *dstPictFRef ) ;
  50. PicHandle ImageToPict( DocumentPtr theDocument, WindowPtr theWindow ) ;
  51. void DoSaveAs(DocumentPtr theDocument)  ;
  52.  
  53. //-------------------------------------------------------------------------------------------
  54. //
  55.  
  56. Boolean         gQuitFlag         = false ;
  57. WindowPtr        gMainWindow        = nil ;
  58. DocumentRec        gDocument ;
  59.  
  60. //-------------------------------------------------------------------------------------------
  61. // main()
  62. // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
  63. // and enter the main event loop.  On exit from the main event loop, we want to call
  64. // the QuickDraw 3D exit function to clean up QuickDraw 3d.
  65.  
  66. void main(void)
  67. {
  68.     TQ3Status    myStatus;
  69.     Rect        rBounds = { 50, 50, 350, 350 } ;
  70.     Str255        title = "\pSpinning Box" ;
  71.     FSSpec        theFileSpec ;                // the file we are opening
  72.  
  73.     InitToolbox() ;
  74.  
  75.     if(MetafileFileSpecify( &theFileSpec )) {
  76.     
  77.         SetCursor(*(GetCursor(watchCursor)));
  78.         
  79.         //    Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
  80.         myStatus = Q3Initialize();
  81.         if ( myStatus == kQ3Failure )
  82.             DebugStr("\pErInitialize returned failure.");            
  83.     
  84.         // install the error & warning handler - these get called whenever
  85.         // errors or warnings occur, which means we don't have to check so 
  86.         // much
  87.         Q3Error_Register( MyErrorHandler, 0L );        
  88.         Q3Warning_Register( MyWarningHandler, 0L );        
  89.     
  90.         // set up our globals
  91.         gQuitFlag = false ;
  92.         gMainWindow = NewCWindow(nil,&rBounds,title,false,noGrowDocProc,(WindowPtr)-1,true,nil); ;
  93.  
  94.         // initialise our document structure
  95.         InitDocumentData( &gDocument ) ;
  96.         
  97.         // try to read the file into the main display group
  98.         if((gDocument.fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) {        
  99.  
  100.             AdjustCamera(    &gDocument,
  101.                             (gMainWindow->portRect.right - gMainWindow->portRect.left),
  102.                             (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
  103.  
  104.             SetWTitle( gMainWindow, theFileSpec.name );
  105.             ShowWindow( gMainWindow ) ;
  106.             SetPort( gMainWindow ) ;
  107.     
  108.             SetCursor(&qd.arrow) ;
  109.             MainEventLoop();
  110.             
  111.         }
  112.                 
  113.         DisposeDocumentData( &gDocument ) ;
  114.         
  115.         //    Close our connection to the QuickDraw 3D library
  116.         myStatus = Q3Exit();
  117.         if ( myStatus == kQ3Failure )
  118.             DebugStr("\pErExit returned failure.");
  119.     }    
  120. }
  121.  
  122. //-------------------------------------------------------------------------------------------
  123. //
  124.  
  125. void InitDocumentData( DocumentPtr theDocument ) 
  126. {
  127.     GWorldPtr        theOffscreen ;
  128.     GDHandle        theDevice ;
  129.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  130.     
  131.     // create a GWorld the size of the window area
  132.     OSErr myErr = NewGWorld(    &theDocument->fGWorld,
  133.                                 32,
  134.                                 &gMainWindow->portRect,
  135.                                 nil,
  136.                                 nil,
  137.                                 0L );
  138.     
  139.     if(myErr != noErr )
  140.         goto bail ;
  141.         
  142.     GetGWorld( &theOffscreen, &theDevice ) ;
  143.     SetGWorld( theDocument->fGWorld, nil ) ;
  144.     EraseRect( &gMainWindow->portRect ) ;
  145.     SetGWorld( theOffscreen, theDevice ) ;
  146.     
  147.     // sets up the 3d data for the scene
  148.     //    Create view for QuickDraw 3D.
  149.     theDocument->fView = MyNewView( theDocument->fGWorld );
  150.  
  151.     // the main display group:
  152.     theDocument->fModel = NULL ;
  153.     
  154.     // scale and group center
  155.     theDocument->fGroupScale = 1;                
  156.     theDocument->fGroupCenter = myOrigin ;    
  157.     
  158.     // the drawing styles:
  159.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  160.     theDocument->fBackFacing = Q3BackfacingStyle_New( kQ3BackfacingStyleBoth ) ;
  161.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  162.  
  163.     // set the rotation matrix the identity matrix
  164.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);    
  165.                     
  166.     return ;
  167.     
  168. bail:
  169.     // we failed setting up the GWorld
  170.     // so we want to quit here
  171.     ExitToShell() ;
  172.     
  173. }
  174.  
  175. void DisposeDocumentData( DocumentPtr theDocument)
  176. {
  177.     Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  178.     Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  179.     Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  180.     Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  181.     Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  182. }
  183. //-----------------------------------------------------------------------------
  184. // assumes the port is set up before being called
  185.  
  186. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  187. {    
  188.     TQ3Status theStatus ;    
  189. //{
  190. //    TQ3CameraData        theCameraData ;
  191. //    TQ3CameraObject        theCameraObject;
  192. //    
  193. //    Q3View_GetCamera(theDocument->fView, &theCameraObject);
  194. //    Q3Camera_GetData(theCameraObject, &theCameraData);
  195. //Debugger() ;
  196. //
  197. //}
  198.  
  199.     //    Start rendering.
  200.     Q3View_StartRendering(theDocument->fView) ;
  201.     do {
  202.         theStatus = SubmitScene( theDocument ) ;
  203.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  204.  
  205.     return theStatus ;    
  206. }
  207.  
  208. //-------------------------------------------------------------------------------------------
  209. //
  210.  
  211. void DocumentDrawOnscreen(DocumentPtr theDocument, Rect *clipRect)
  212. {
  213.     if (theDocument->fGWorld) {
  214.     
  215.         CGrafPtr            savedPort;
  216.         GDHandle            savedDevice;
  217.  
  218.         GetGWorld( &savedPort, &savedDevice);
  219.         SetGWorld( (CGrafPtr)gMainWindow,  nil);
  220.         
  221.         ClipRect( clipRect ) ;
  222.         
  223.         // don't need to lockPixels on the GWorld as the 
  224.         // offscreen remains locked (see IM: QD3D), the
  225.         // pixmap for a pixmap draw context must remain locked
  226.         
  227.         CopyBits ((BitMapPtr) &theDocument->fGWorld->portPixMap,
  228.                   &gMainWindow->portBits,
  229.                   &theDocument->fGWorld->portRect, 
  230.                   &gMainWindow->portRect,
  231.                   srcCopy, 
  232.                   0L);
  233.                   
  234.         SetGWorld( savedPort, savedDevice);
  235.       }
  236. }
  237.  
  238. //--------------------------------------------------------------------------------------
  239.  
  240. OSErr WritePict( PicHandle myPic, short  dstPictFRef )
  241. {
  242.      long                    length ;
  243.     long                    dummy ;
  244.     int                        index ;
  245.     OSErr                    result ;
  246.  
  247.      // ok, myPic now contains a handle to the compressed picture
  248.                         
  249.     HLock( (Handle)(Handle)myPic);
  250.  
  251.    // set up the 512 byte header for a PICT file 
  252.     dummy = 0;
  253.     
  254.     for( index = 0; index < ( 512 / 4 ); index ++ ){
  255.         length = 4 ;
  256.            
  257.            if( (result = FSWrite(dstPictFRef, &length, &dummy)) != noErr ) {
  258.                // ErrorAlert( rErrorStrs, eCantWriteFile );
  259.             return result ;        
  260.         }
  261.     }                
  262.     
  263.        length = GetHandleSize( (Handle)myPic);
  264.       
  265.        if( (result = FSWrite(dstPictFRef, &length, *myPic)) != noErr ) {
  266.            //ErrorAlert( rErrorStrs, eCantWriteFile );
  267.         return result ;        
  268.     }
  269.  
  270.        // now get rid of the picture handle 
  271.     HUnlock( (Handle) (Handle)myPic ) ;
  272.        KillPicture(myPic);
  273.  
  274.      return noErr ;
  275. }
  276.  
  277. //--------------------------------------------------------------------------------------
  278.  
  279.  
  280. OSErr GetOutputFileRef(short    *dstPictFRef ) // GetOutputFileRefNum
  281. {
  282.     StandardFileReply    aPictSFR;    // new style Standard file record 
  283.     OSErr                result ;
  284.     SFTypeList     types = { 'PICT',0 };        // we are only interested in PICT files
  285.         
  286.     // check to see if we have the new style standard file package
  287.  
  288.     StandardPutFile( "\pSave PICT as:", "\pNew PICT", &aPictSFR);
  289.     if ( aPictSFR.sfGood  ) {
  290.         
  291.         // Delete the file of the same name, if one exits, 
  292.         // and create a new PICT file.
  293.         
  294.         FSpDelete(&aPictSFR.sfFile);
  295.         
  296.         result = FSpCreate( &aPictSFR.sfFile,'????','PICT', aPictSFR.sfScript);
  297.         if (result != noErr) {
  298.             return result;
  299.         }
  300.         
  301.         // open the data fork for writing
  302.         // ??? need to change the permissions here ???
  303.         
  304.         result = FSpOpenDF( &aPictSFR.sfFile, fsCurPerm, dstPictFRef);
  305.         if (result != noErr) {
  306.             return result;
  307.         }
  308.     }
  309.     else 
  310.         return userCanceledErr ;
  311.         
  312.     return noErr ;
  313. }
  314. //--------------------------------------------------------------------------------------
  315. PicHandle ImageToPict( DocumentPtr theDocument, WindowPtr theWindow )
  316. {
  317.     PicHandle thePicture = OpenPicture(&theDocument->fGWorld->portRect) ;
  318.     DocumentDrawOnscreen( theDocument, &theWindow->portRect) ;
  319.     ClosePicture() ;
  320.     return thePicture ;
  321. }
  322.  
  323. //--------------------------------------------------------------------------------------
  324.  
  325. void DoSaveAs(DocumentPtr theDocument) 
  326. {
  327.     short                dstPictFRef = 0;
  328.     PicHandle            myPic = nil;
  329.     OSErr                theErr;
  330.     extern gxShape         gthePicture;        // defined in BitmAp Shape with Clip.c
  331.     
  332.     // get an open a file for writing
  333.     if( (theErr = GetOutputFileRef( &dstPictFRef )) != noErr ) {
  334.         return ;
  335.     } 
  336.     else {
  337.         if(( myPic = ImageToPict ( theDocument, gMainWindow )) != nil ) {
  338.             if(WritePict( myPic, dstPictFRef ) != noErr ) {
  339.                 FSClose(dstPictFRef);
  340.                 return ;
  341.             }
  342.         }
  343.     }
  344.     
  345.     FSClose(dstPictFRef);
  346.  
  347.     return ;
  348.  
  349. }
  350. //-------------------------------------------------------------------------------------------
  351. //
  352.  
  353. short HiWrd(long aLong)
  354. {
  355.     return    (((aLong) >> 16) & 0xFFFF) ;
  356. }
  357.  
  358. //-------------------------------------------------------------------------------------------
  359. //
  360.  
  361. short LoWrd(long aLong)
  362. {
  363.     return    ((aLong) & 0xFFFF) ;
  364.  
  365. }
  366.  
  367. //-------------------------------------------------------------------------------------------
  368. //
  369.  
  370. void InitToolbox()
  371. {
  372.     Handle        menuBar = nil;
  373.  
  374.     MaxApplZone() ;
  375.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  376.     
  377.     InitGraf( &qd.thePort );
  378.     InitFonts();
  379.     InitWindows();
  380.  
  381.     FlushEvents( everyEvent, 0 ) ;
  382.     // initialize application globals
  383.     
  384.     gQuitFlag = false;
  385.     InitCursor();
  386.     
  387. }
  388.  
  389. //-------------------------------------------------------------------------------------------
  390. //
  391. void MainEventLoop()
  392. {
  393.     EventRecord     event;
  394.     WindowPtr       window;
  395.     short           thePart;
  396.     Rect            screenRect, updateRect;
  397.     Point            aPoint = {100, 100};
  398.     
  399.  
  400.     while( !gQuitFlag )
  401.     {
  402.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  403.         {
  404.  
  405.             switch (event.what) {
  406.                 case mouseDown:
  407.                 
  408.                     thePart = FindWindow( event.where, &window );
  409.                     
  410.                     switch( thePart ) {
  411.                         case inMenuBar: 
  412.                             break;
  413.                         
  414.                         case inDrag:
  415.                     
  416.                             screenRect = (**GetGrayRgn()).rgnBBox;
  417.                             DragWindow( window, event.where, &screenRect );
  418.                             break ;
  419.                     
  420.                         case inContent:
  421.                     
  422.                             if (window != FrontWindow())
  423.                                 SelectWindow( window );
  424.                             break ;
  425.                     
  426.                         case inGoAway:
  427.                             if (TrackGoAway( window, event.where )) {
  428.                                 DoSaveAs(&gDocument) ;
  429.                                 DisposeWindow ( window );
  430.                                 gQuitFlag = true;
  431.  
  432.                             }
  433.                             break ;
  434.                             
  435.                         default:
  436.                             break ;
  437.                     }
  438.                     break ;
  439.                             
  440.                         
  441.                 case updateEvt:
  442.                 
  443.                     window = (WindowPtr)event.message;
  444.                     updateRect = (**(window->visRgn)).rgnBBox;
  445.                     SetPort( window ) ;
  446.                     BeginUpdate( window );
  447.                     DocumentDraw3DData( &gDocument ) ;
  448.                     DocumentDrawOnscreen( &gDocument, &updateRect ) ;
  449.                     EndUpdate( window );
  450.  
  451.                     break ;
  452.                     
  453.                 case keyDown:
  454.                 case autoKey:
  455.                     HandleKeyPress(&event);
  456.                     break;
  457.                     
  458.                 case diskEvt:
  459.                     if ( HiWrd(event.message) != noErr ) 
  460.                         (void) DIBadMount(aPoint, event.message);
  461.                     break;
  462.                     
  463.                 case osEvt:
  464.                 case activateEvt:
  465.                     break;
  466.  
  467.  
  468.             }
  469.         }
  470.         else {
  471.             // we received a null event, rotate the cube
  472.             TQ3Matrix4x4    tmp;
  473.             Rect        theRect = ((GrafPtr)gMainWindow)->portRect ;
  474.             
  475.             SetPort((GrafPtr)gMainWindow) ;
  476.             Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
  477.             Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
  478.  
  479.             InvalRect( &theRect ) ;
  480.         }
  481.     }
  482. }
  483.  
  484.  
  485. //-------------------------------------------------------------------------------------------
  486. //
  487. void HandleKeyPress(EventRecord *event)
  488. {}
  489.  
  490. //-------------------------------------------------------------------------------------------
  491. //
  492.  
  493.  
  494.  
  495.